package org.pixelami.hercularity.tests
{
	
	import flash.events.ErrorEvent;
	import flash.events.Event;
	
	import org.flexunit.Assert;
	import org.flexunit.async.Async;
	import org.pixelami.hercularity.Step;
	import org.pixelami.hercularity.conditions.Condition;
	import org.pixelami.hercularity.descriptors.Action;
	import org.pixelami.hercularity.descriptors.DeferredAction;
	import org.pixelami.hercularity.events.StepErrorEvent;
	import org.pixelami.hercularity.events.StepEvent;
	import org.pixelami.hercularity.tests.mocks.StepConditions;
	import org.pixelami.hercularity.tests.mocks.TestTaskAsync;
	
	
	
	public class DeferredActionTests
	{		
		[Before]
		public function setUp():void
		{
		}
		
		[After]
		public function tearDown():void
		{
		}
		
		[BeforeClass]
		public static function setUpBeforeClass():void
		{
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
		}
		
		[Test(async,timeout="1000",description="Tests Deferred Actions with constructor arguments")]
		public function testStepWithDeferredActionsThatFailFatally():void
		{
			var step1:Step = new Step(
				new DeferredAction(TestTaskAsync,[TestTaskAsync.SUCCEED],Action.PROCEED_ON_ERROR),
				new DeferredAction(TestTaskAsync,[TestTaskAsync.SUCCEED],Action.PROCEED_ON_ERROR)
			);
			
			var step2:Step = new Step(
				new DeferredAction(TestTaskAsync,[TestTaskAsync.FAIL],Action.PROCEED_ON_ERROR),
				new DeferredAction(TestTaskAsync,[TestTaskAsync.SUCCEED],Action.PROCEED_ON_ERROR)
			);
			
			var condition1:Condition = new Condition(StepConditions,"AtLeastOneActionCompleted");
			
			var step3:Step = new Step(
				new DeferredAction(TestTaskAsync,[TestTaskAsync.SUCCEED],Action.PROCEED_ON_ERROR),
				new DeferredAction(TestTaskAsync,[TestTaskAsync.FAIL,20],Action.BREAK_ON_ERROR)
			);
			
			
			step1.thenDo(step2.thenIf(condition1).thenDo(step3));
			
			
			step1.addEventListener(StepEvent.STEP_COMPLETE,OnStepFailOrComplete);
			step1.addEventListener(StepErrorEvent.STEP_ERROR,OnStepFailOrComplete);
			//Async.proceedOnEvent(this,s,StepEvent.STEP_COMPLETE,1000);
			Async.proceedOnEvent(this,step1,StepErrorEvent.STEP_ERROR,1000);
			step1.run();
			
			//Assert.assertNull(step2.actions);
			//Assert.assertNull(step3.actions);
		}
		
		public function OnStepFailOrComplete(event:Event):void
		{
			trace(event);
			var errorLength:uint = event.target.getErrorStack().length;
			trace("errorLength: "+errorLength);
			Assert.assertEquals(2,errorLength);
			
			var err:StepErrorEvent = event as StepErrorEvent;
			trace(err.errorTarget.errorEvent);
			
			var firstFailedAction:Action = event.target.getErrorStack()[0];
			trace(firstFailedAction.errorEvent);
			Assert.assertTrue(firstFailedAction.errorEvent is ErrorEvent && !(firstFailedAction.errorEvent is StepErrorEvent));
		}
		
		
	}
}